import os
from flask import Flask, render_template, request, redirect, url_for, send_from_directory, session, make_response, \
    send_file
import json
import time

app = Flask(__name__)
app.secret_key = 'your_secret_key'  # 用于会话管理，请务必更换为强随机密钥
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0

# Set the folder where the files will be stored
UPLOAD_FOLDER = 'shared_folders'
if not os.path.exists(UPLOAD_FOLDER):
    os.makedirs(UPLOAD_FOLDER)

app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

# 设置 JSON 文件路径
USER_DATA_FILE = 'zy5.json'

valid_users = json.load(open(USER_DATA_FILE, 'r'))


# 根路由，返回index.html页面
@app.route('/')
def index():
    if 'user' in session:
        folders = [f for f in os.listdir(app.config['UPLOAD_FOLDER']) if
                   os.path.isdir(os.path.join(app.config['UPLOAD_FOLDER'], f))]
        print(f"Detected folders: {folders}")  # 打印文件夹列表以调试
        can_create_folder = session['user'] == 'root'
        folders = get_directory_structure(UPLOAD_FOLDER)
        return render_template('index.html', folders=folders, render_subfolders=render_subfolders,
                               can_create_folder=can_create_folder)  # 根据地址跳转到页面
    return redirect(url_for('login'))


def render_subfolders(subfolders, parent_folder):
    html = '<ul class="subfolder" style="display: none;">'
    for subfolder, children in subfolders.items():
        full_path = f"{parent_folder}/{subfolder}"  # 组合路径
        html += f'<li class="list-group-item second">' \
                f'<span class="folder" onclick="toggleFolder(this)">' \
                f'<a href="/folder/{full_path}">{subfolder}</a></span>'
        if children:
            html += render_subfolders(children, full_path)  # 递归调用并传递完整路径
        html += '</li>'
    html += '</ul>'
    return html


app.add_template_filter(render_subfolders)


# 生成文件夹结构树
def get_directory_structure(rootdir):
    folder_structure = {}

    for dirpath, dirnames, _ in os.walk(rootdir):
        rel_path = os.path.relpath(dirpath, rootdir)
        if rel_path == "." or rel_path == "":
            continue

        parts = rel_path.split(os.sep)
        current_level = folder_structure

        for part in parts:
            if part not in current_level:
                current_level[part] = {}
            current_level = current_level[part]

    return folder_structure


@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        student_id = request.form['student_id']
        name = request.form['name']
        # 验证学号和姓名
        if valid_users.get(name) == student_id:
            session['user'] = student_id  # 将用户信息存储在会话中
            return redirect(url_for('index'))
        else:
            return "学号和密码不对应，请重新输入！"
    return render_template('login.html')


@app.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'POST':
        # 获取表单数据
        student_id = request.form['student_id']
        name = request.form['name']

        # 构建用户信息字典
        user_data = {
            name: student_id
        }

        # 将新用户数据添加到用户列表
        # 读取现有用户数据
        with open(USER_DATA_FILE, 'r') as f:
            try:
                users = json.load(f)  # 尝试加载 JSON 数据
            except json.JSONDecodeError:
                users = {}  # 如果发生错误，初始化为空字典

        # 检查学生 ID 是否已存在
        if student_id in users.values():
            # 如果存在，可能选择更新名字或提示用户
            return render_template('login.html', message="学号已存在，请登录。")

        users.update(user_data)

        # 将更新后的用户数据写入 JSON 文件
        with open(USER_DATA_FILE, 'w') as f:
            json.dump(users, f, indent=4)

        return redirect(url_for('login'))

    return render_template('register.html')


# Route to create a new folder
@app.route('/create_folder', methods=['POST'])
def create_folder():
    folder_name = request.form['folder_name']
    print(folder_name)
    folder_path = os.path.join(app.config['UPLOAD_FOLDER'], folder_name)
    if not os.path.exists(folder_path):
        os.makedirs(folder_path)
    return redirect(url_for('index'))


# Route to display files in a folder
@app.route('/folder/<path:folder_name>')
def folder_view(folder_name):
    folder_path = os.path.join(app.config['UPLOAD_FOLDER'], folder_name)
    files = [f for f in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, f))]

    # 获取当前用户的学号
    user_id = session.get('user', '')
    downloadable_files = [f for f in files if user_id in f]

    can_create_folder = session['user'] == 'root'

    return render_template('folder.html', can_create_folder=can_create_folder, folder_name=folder_name, files=files,
                           downloadable_files=downloadable_files)


# Route to handle file uploads
@app.route('/upload/<path:folder_name>', methods=['POST'])
def upload_file(folder_name):
    folder_path = os.path.join(app.config['UPLOAD_FOLDER'], folder_name)
    if 'file' not in request.files:
        return "No file selected", 400
    file = request.files['file']
    if file.filename == '':
        return "No selected file", 400
    file.save(os.path.join(folder_path, file.filename))
    return redirect(url_for('folder_view', folder_name=folder_name))


# Route to download a file
@app.route('/download/<path:folder_name>/<filename>')
def download_file(folder_name, filename):
    folder_path = os.path.join(app.config['UPLOAD_FOLDER'], folder_name)
    file_path = os.path.join(folder_path, filename)

    # 获取文件的最后修改时间
    if os.path.exists(file_path):
        last_modified = str(int(os.path.getmtime(file_path)))
        response = make_response(send_file(file_path))
        response.headers['Cache-Control'] = 'no-store'
        response.headers['ETag'] = last_modified
        return response
    else:
        return "File not found", 404


# Route to delete a file
@app.route('/delete_file/<path:folder_name>/<filename>')
def delete_file(folder_name, filename):
    folder_path = os.path.join(app.config['UPLOAD_FOLDER'], folder_name)
    file_path = os.path.join(folder_path, filename)
    if os.path.exists(file_path):
        os.remove(file_path)
    return redirect(url_for('folder_view', folder_name=folder_name))


# Route to delete a folder
@app.route('/delete_folder/<folder_name>')
def delete_folder(folder_name):
    folder_path = os.path.join(app.config['UPLOAD_FOLDER'], folder_name)
    if os.path.exists(folder_path):
        os.rmdir(folder_path)
    return redirect(url_for('index'))


if __name__ == '__main__':
    app.run(debug=False, port=5001, host="10.10.14.166")
